package psd.model;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.runtime.IProgressMonitor;

import psd.model.Prolog.JPLQueryExecuter;

public class RuleSet {
	private List<Rule> rules = new ArrayList<Rule>();
	private String fileName;
	private String name = "";
	private String description = "";
	private String version;

	/**
	 * Returns the number of rules in this ruleset
	 * 
	 * @return an int representing the number of rules
	 */
	public int size() {
		return rules.size();
	}

	/**
	 * Add a new rule to this ruleset
	 * 
	 * @param rule
	 *            the rule to be added
	 */
	public void addRule(Rule rule) {
		if (rule == null) {
			throw new RuntimeException(
					"Null Rule reference added to a RuleSet; that's a bug somewhere in PMD");
		}
		rules.add(rule);
	}

	public Collection<Rule> getRules() {
		return rules;
	}

	/**
	 * Returns the Rule with the given name
	 * 
	 * @param ruleName
	 *            the name of the rule to find
	 * @return the rule or null if not found
	 */
	public Rule getRuleByName(String ruleName) {
		Rule rule = null;
		for (Iterator<Rule> i = rules.iterator(); i.hasNext() && rule == null;) {
			Rule r = i.next();
			if (r.getName().equals(ruleName)) {
				rule = r;
			}
		}
		return rule;
	}

	/**
	 * Add a whole RuleSet to this RuleSet
	 * 
	 * @param ruleSet
	 *            the RuleSet to add
	 */
	public void addRuleSet(RuleSet ruleSet) {
		rules.addAll(rules.size(), ruleSet.getRules());
	}

	/*
	 * public void apply() { for (Rule rule : rules) { rule.Validate(new AST); }
	 * }
	 */

	public String getFileName() {
		return fileName;
	}

	public void setFileName(String fileName) {
		this.fileName = fileName;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getDescription() {
		return description;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	public void setVersion(String version) {
		this.version = version;
	}

	public String getVersion() {
		return version;
	}

	public void runRules(IProgressMonitor monitor) {
		monitor.beginTask("Rules executing", rules.size());
//		JPLQueryExecuter.LoadMetaModel();
		for (Rule rule : rules) {
			try {
				List<Bug> bugsFound = rule.execute();
				for (Bug bug : bugsFound) {
					bug.Print();
					bug.StoreStadistic();
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
			monitor.worked(1);
		}
	}

}
